/**
 * Copyright (c) 2014-now, secondriver (secondriver@yeah.net).
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package secondriver.jfinal.rack.kit;

import java.util.Calendar;
import java.util.Random;
import java.util.regex.Pattern;

/**
 * 1999年7月1日生效的GB11643-1999《公民身份号码》
 * 
 * @author secondriver
 * @time 2013-10-29
 */
public class RockChinaIdKit {

	private static final String REGPEX_18_BIT = "^(\\d{6})(\\d{4})(\\d{2})(\\d{2})(\\d{3})([0-9]|X)$";
	private static final String REGPEX_15_BIT = "^(\\d{6})(\\d{2})(\\d{2})(\\d{2})(\\d{3})$";
	private static final String BIRTHDAY_18_BIT = "^((19|20)\\d{2})(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])$";
	private static final String BIRTHDAY_15_BIT = "^(\\d{2})(0[1-9]|1[0-2])(0[1-9]|[12][0-9]|3[01])$";

	/**
	 * 身份证校验位值
	 */
	private static final char[] CHINA_IDCARD_VALIDATE_BIT = new char[] { '1',
			'0', 'X', '9', '8', '7', '6', '5', '4', '3', '2' };

	/**
	 * 校验身份证是否编码上有效
	 * 
	 * @param idcard
	 * @return
	 */
	public static boolean isValid(String idcard) {
		int idsize = idcard.length();
		boolean result = false;
		if (idsize == 15) {
			result = validateFormate(idcard) && validateBirthday(idcard)
					&& validateLastBit(idcard);
		}
		if (idsize == 18) {
			result = validateFormate(idcard) && validateBirthday(idcard)
					&& validateLastBit(idcard) && validateAddressCode(idcard);
		}
		return result;
	}

	/**
	 * 根据1999年7月1日生效的GB11643-1999《公民身份号码》规定动态生成身份证号码
	 * 
	 * 注意：生成的身份证号码仅仅是格式有效，并不代表真实存在
	 * 
	 * 在身份证数据库的身份证才有效
	 * 
	 * @return
	 */
	public static String generator() {
		Random r = new Random();
		// 地址码
		String addresscode = String.valueOf(CHINA_ADDRESS_CODE[r
				.nextInt(CHINA_ADDRESS_CODE.length)]);

		// 年份
		int currentYear = Calendar.getInstance().get(Calendar.YEAR);
		int year = r.nextInt(currentYear - 1900 + 1) + 1900;
		String syear = String.valueOf(year);

		// 月份
		int month = (year == currentYear) ? (r.nextInt(Calendar.getInstance()
				.get(Calendar.MONTH) + 1) + 1) : (r.nextInt(12) + 1);
		String smonth = String.valueOf((month <= 9 ? "0" + month : month));

		// 日期
		int day = (month == Calendar.getInstance().get(Calendar.MONTH) + 1) ? (r
				.nextInt(Calendar.getInstance().get(Calendar.DAY_OF_MONTH)) + 1)
				: (r.nextInt(getDays(month, year)) + 1);
		String sday = String.valueOf((day <= 9) ? "0" + day : day);

		// 顺序码
		int v;
		String sequence = String
				.valueOf(((v = r.nextInt(1000)) <= 99 ? (v > 9 ? "0" + v : "00"
						+ v) : v));

		// 18位身份证，？占位，用来填充有效的校验位
		String id18 = addresscode + syear + smonth + sday + sequence + "?";

		// 校验位
		int value = getValidateValue(id18);
		String lastbit = CHINA_IDCARD_VALIDATE_BIT[value] + "";
		return id18.substring(0, id18.length() - 1) + lastbit;
	}

	/**
	 * 检验身份证格式
	 * 
	 * @param idcard
	 * @return
	 */
	private static boolean validateFormate(String idcard) {
		return Pattern.matches(REGPEX_18_BIT, idcard)
				|| Pattern.matches(REGPEX_15_BIT, idcard);
	}

	/**
	 * 校验身份证验证位是否有效
	 * 
	 * @param idcard
	 * @return
	 */
	private static boolean validateLastBit(String idcard) {
		char validateBit = idcard.charAt(idcard.length() - 1);
		int validateValue = getValidateValue(idcard);
		return CHINA_IDCARD_VALIDATE_BIT[validateValue] == validateBit;
	}

	/**
	 * 校验生日信息
	 * 
	 * @param idcard
	 * @return
	 */
	private static boolean validateBirthday(String idcard) {
		int bitSize = idcard.length();
		boolean result = false;
		if (bitSize == 15) {
			String birthday = idcard.substring(6, 12);
			if (Pattern.matches(BIRTHDAY_15_BIT, birthday)) {
				result = checkDate(birthday);
			}
		}
		if (bitSize == 18) {
			String birthday = idcard.substring(6, 14);
			if (Pattern.matches(BIRTHDAY_18_BIT, birthday)) {
				result = checkDate(birthday);
			}
		}
		return result;
	}

	/**
	 * 校验身份证地址码
	 * 
	 * @param idcard
	 * @return
	 */
	private static boolean validateAddressCode(String idcard) {
		int addcode = Integer.parseInt(idcard.substring(0, 6));
		boolean result = false;
		for (int i = 0; i < CHINA_ADDRESS_CODE.length; i++) {
			if (CHINA_ADDRESS_CODE[i] == addcode) {
				result = true;
				break;
			}
		}
		return result;
	}

	/**
	 * 判断是否闰年
	 * 
	 * @param year
	 * @return
	 */
	private static boolean isLeap(int year) {
		return (year % 4 == 0 && year % 100 != 0 || (year % 400 == 0));
	}

	/**
	 * 获取指定年月的月的天数
	 * 
	 * @param month
	 * @param year
	 * @return
	 */
	private static int getDays(int month, int year) {
		int day = 30;
		if (month == 1 || month == 3 || month == 5 || month == 7 || month == 8
				|| month == 10 || month == 12) {
			day = 31;
		} else if (month == 2) {
			if (isLeap(year)) {
				day = 29;
			} else {
				day = 28;
			}
		}
		return day;
	}

	/**
	 * 检查日期是否有效
	 * 
	 * @param birthday
	 * @return
	 */
	private static boolean checkDate(String birthday) {
		String syear = "1900";
		String smonth = "01";
		String sday = "01";
		if (birthday.length() == 6) {
			syear = "19" + birthday.substring(0, 2);
			smonth = birthday.substring(2, 4);
			sday = birthday.substring(4, 6);
		}
		if (birthday.length() == 8) {
			syear = birthday.substring(0, 4);
			smonth = birthday.substring(4, 6);
			sday = birthday.substring(6, 8);
		}
		int year = Integer.parseInt(syear);
		int month = Integer
				.parseInt(smonth.substring(0, 1).equals("0") ? smonth
						.substring(1, 2) : smonth);
		int day = Integer.parseInt(sday.substring(0, 1).equals("0") ? sday
				.substring(1, 2) : sday);
		boolean result = false;
		if (year >= 1900 && year < Calendar.getInstance().get(Calendar.YEAR)) {
			if (month >= 1 && month <= 12) {
				if (day >= 1 && day <= getDays(month, year)) {
					result = true;
				}
			}
		}
		if (year == Calendar.getInstance().get(Calendar.YEAR)) {
			if (month >= 1
					&& month < Calendar.getInstance().get(Calendar.MONTH) + 1) {
				if (day >= 1 && day <= getDays(month, year)) {
					result = true;
				}
			}
			if (month == Calendar.getInstance().get(Calendar.MONTH) + 1) {
				if (day >= 0
						&& day <= Calendar.getInstance().get(
								Calendar.DAY_OF_MONTH)) {
					result = true;
				}
			}
		}
		return result;
	}

	/**
	 * 获取身份证号码18-1(从左至右)每一位的权重值
	 * 
	 * @return
	 */
	private static int[] getEveryBitWeightValue() {
		int[] weightValueArray = new int[18];
		for (int i = 18, j = 0; i >= 1; i--, j++) {
			weightValueArray[j] = (int) (Math.pow(2, i - 1) % 11);
		}
		return weightValueArray;
	}

	/**
	 * 计算校验值
	 * 
	 * @param idcard
	 * @return
	 */
	private static int getValidateValue(String idcard) {
		char[] bits = idcard.toCharArray();
		int result = 0;
		int[] weigthValueArray = getEveryBitWeightValue();
		for (int i = 0, j = idcard.length() - 1; i < j; i++) {
			result += Integer.parseInt(bits[i] + "") * weigthValueArray[i];
		}
		return result % 11;
	}

	/**
	 * 中国大陆居民身份证地址码省(自治区，直辖市)市区县编码
	 * 
	 * @author ZhangXiao
	 * @time 2013-10-29
	 */
	static final int[] CHINA_ADDRESS_CODE = new int[] { 110000, 110100, 110101,
			110102, 110103, 110104, 110105, 110106, 110107, 110108, 110109,
			110111, 110112, 110113, 110200, 110221, 110224, 110226, 110227,
			110228, 110229, 120000, 120100, 120101, 120102, 120103, 120104,
			120105, 120106, 120107, 120108, 120109, 120110, 120111, 120112,
			120113, 120200, 120221, 120222, 120223, 120224, 120225, 130000,
			130100, 130101, 130102, 130103, 130104, 130105, 130106, 130107,
			130121, 130123, 130124, 130125, 130126, 130127, 130128, 130129,
			130130, 130131, 130132, 130133, 130181, 130182, 130183, 130184,
			130185, 130200, 130201, 130202, 130203, 130204, 130205, 130206,
			130221, 130223, 130224, 130225, 130227, 130229, 130230, 130281,
			130282, 130283, 130300, 130301, 130302, 130303, 130304, 130321,
			130322, 130323, 130324, 130400, 130401, 130402, 130403, 130404,
			130406, 130421, 130423, 130424, 130425, 130426, 130427, 130428,
			130429, 130430, 130431, 130432, 130433, 130434, 130435, 130481,
			130500, 130501, 130502, 130503, 130521, 130522, 130523, 130524,
			130525, 130526, 130527, 130528, 130529, 130530, 130531, 130532,
			130533, 130534, 130535, 130581, 130582, 130600, 130601, 130602,
			130603, 130604, 130621, 130622, 130623, 130624, 130625, 130626,
			130627, 130628, 130629, 130630, 130631, 130632, 130633, 130634,
			130635, 130636, 130637, 130638, 130681, 130682, 130683, 130684,
			130700, 130701, 130702, 130703, 130705, 130706, 130721, 130722,
			130723, 130724, 130725, 130726, 130727, 130728, 130729, 130730,
			130731, 130732, 130733, 130800, 130801, 130802, 130803, 130804,
			130821, 130822, 130823, 130824, 130825, 130826, 130827, 130828,
			130900, 130901, 130902, 130903, 130921, 130922, 130923, 130924,
			130925, 130926, 130927, 130928, 130929, 130930, 130981, 130982,
			130983, 130984, 131000, 131001, 131002, 131022, 131023, 131024,
			131025, 131026, 131028, 131081, 131082, 131100, 131101, 131102,
			131121, 131122, 131123, 131124, 131125, 131126, 131127, 131128,
			131181, 131182, 140000, 140100, 140101, 140105, 140106, 140107,
			140108, 140109, 140110, 140121, 140122, 140123, 140181, 140200,
			140201, 140202, 140203, 140211, 140212, 140221, 140222, 140223,
			140224, 140225, 140226, 140227, 140300, 140301, 140302, 140303,
			140311, 140321, 140322, 140400, 140401, 140402, 140411, 140421,
			140423, 140424, 140425, 140426, 140427, 140428, 140429, 140430,
			140431, 140481, 140500, 140501, 140502, 140521, 140522, 140524,
			140525, 140581, 140600, 140601, 140602, 140603, 140621, 140622,
			140623, 140624, 142200, 142201, 142202, 142222, 142223, 142225,
			142226, 142227, 142228, 142229, 142230, 142231, 142232, 142233,
			142234, 142300, 142301, 142302, 142303, 142322, 142323, 142325,
			142326, 142327, 142328, 142329, 142330, 142332, 142333, 142400,
			142401, 142402, 142421, 142422, 142423, 142424, 142427, 142429,
			142430, 142431, 142433, 142600, 142601, 142602, 142603, 142621,
			142622, 142623, 142625, 142627, 142628, 142629, 142630, 142631,
			142632, 142633, 142634, 142635, 142636, 142700, 142701, 142702,
			142703, 142723, 142724, 142725, 142726, 142727, 142729, 142730,
			142731, 142732, 142733, 150000, 150100, 150101, 150102, 150103,
			150104, 150105, 150121, 150122, 150123, 150124, 150125, 150200,
			150201, 150202, 150203, 150204, 150205, 150206, 150207, 150221,
			150222, 150223, 150300, 150301, 150302, 150303, 150304, 150400,
			150401, 150402, 150403, 150404, 150421, 150422, 150423, 150424,
			150425, 150426, 150428, 150429, 150430, 152100, 152101, 152102,
			152103, 152104, 152105, 152106, 152122, 152123, 152127, 152128,
			152129, 152130, 152131, 152200, 152201, 152202, 152221, 152222,
			152223, 152224, 152300, 152301, 152302, 152322, 152323, 152324,
			152325, 152326, 152327, 152500, 152501, 152502, 152522, 152523,
			152524, 152525, 152526, 152527, 152528, 152529, 152530, 152531,
			152600, 152601, 152602, 152624, 152625, 152626, 152627, 152629,
			152630, 152631, 152632, 152634, 152700, 152701, 152722, 152723,
			152724, 152725, 152726, 152727, 152728, 152800, 152801, 152822,
			152823, 152824, 152825, 152826, 152827, 152900, 152921, 152922,
			152923, 210000, 210100, 210101, 210102, 210103, 210104, 210105,
			210106, 210111, 210112, 210113, 210114, 210122, 210123, 210124,
			210181, 210200, 210201, 210202, 210203, 210204, 210211, 210212,
			210213, 210224, 210281, 210282, 210283, 210300, 210301, 210302,
			210303, 210304, 210311, 210321, 210323, 210381, 210400, 210401,
			210402, 210403, 210404, 210411, 210421, 210422, 210423, 210500,
			210501, 210502, 210503, 210504, 210505, 210521, 210522, 210600,
			210601, 210602, 210603, 210604, 210624, 210681, 210682, 210700,
			210701, 210702, 210703, 210711, 210726, 210727, 210781, 210782,
			210800, 210801, 210802, 210803, 210804, 210811, 210881, 210882,
			210900, 210901, 210902, 210903, 210904, 210905, 210911, 210921,
			210922, 211000, 211001, 211002, 211003, 211004, 211005, 211011,
			211021, 211081, 211100, 211101, 211102, 211103, 211121, 211122,
			211200, 211201, 211202, 211204, 211221, 211223, 211224, 211281,
			211282, 211300, 211301, 211302, 211303, 211321, 211322, 211324,
			211381, 211382, 211400, 211401, 211402, 211403, 211404, 211421,
			211422, 211481, 220000, 220100, 220101, 220102, 220103, 220104,
			220105, 220106, 220112, 220122, 220181, 220182, 220183, 220200,
			220201, 220202, 220203, 220204, 220211, 220221, 220281, 220282,
			220283, 220284, 220300, 220301, 220302, 220303, 220322, 220323,
			220381, 220382, 220400, 220401, 220402, 220403, 220421, 220422,
			220500, 220501, 220502, 220503, 220521, 220523, 220524, 220581,
			220582, 220600, 220601, 220602, 220621, 220622, 220623, 220625,
			220681, 220700, 220701, 220702, 220721, 220722, 220723, 220724,
			220800, 220801, 220802, 220821, 220822, 220881, 220882, 222400,
			222401, 222402, 222403, 222404, 222405, 222406, 222424, 222426,
			230000, 230100, 230101, 230102, 230103, 230104, 230105, 230106,
			230107, 230108, 230121, 230123, 230124, 230125, 230126, 230127,
			230128, 230129, 230181, 230182, 230183, 230184, 230200, 230201,
			230202, 230203, 230204, 230205, 230206, 230207, 230208, 230221,
			230223, 230224, 230225, 230227, 230229, 230230, 230231, 230281,
			230300, 230301, 230302, 230303, 230304, 230305, 230306, 230307,
			230321, 230381, 230382, 230400, 230401, 230402, 230403, 230404,
			230405, 230406, 230407, 230421, 230422, 230500, 230501, 230502,
			230503, 230505, 230506, 230521, 230522, 230523, 230524, 230600,
			230601, 230602, 230603, 230604, 230605, 230606, 230621, 230622,
			230623, 230624, 230700, 230701, 230702, 230703, 230704, 230705,
			230706, 230707, 230708, 230709, 230710, 230711, 230712, 230713,
			230714, 230715, 230716, 230722, 230781, 230800, 230801, 230802,
			230803, 230804, 230805, 230811, 230822, 230826, 230828, 230833,
			230881, 230882, 230900, 230901, 230902, 230903, 230904, 230921,
			231000, 231001, 231002, 231003, 231004, 231005, 231024, 231025,
			231081, 231083, 231084, 231085, 231100, 231101, 231102, 231121,
			231123, 231124, 231181, 231182, 232300, 232301, 232302, 232303,
			232304, 232324, 232325, 232326, 232330, 232331, 232332, 232700,
			232721, 232722, 232723, 310000, 310100, 310101, 310102, 310103,
			310104, 310105, 310106, 310107, 310108, 310109, 310110, 310112,
			310113, 310114, 310115, 310116, 310117, 310200, 310225, 310226,
			310229, 310230, 320000, 320100, 320101, 320102, 320103, 320104,
			320105, 320106, 320107, 320111, 320112, 320113, 320114, 320121,
			320122, 320123, 320124, 320125, 320200, 320201, 320202, 320203,
			320204, 320211, 320281, 320282, 320283, 320300, 320301, 320302,
			320303, 320304, 320305, 320311, 320321, 320322, 320323, 320324,
			320381, 320382, 320400, 320401, 320402, 320404, 320405, 320411,
			320481, 320482, 320483, 320500, 320501, 320502, 320503, 320504,
			320511, 320581, 320582, 320583, 320584, 320585, 320586, 320600,
			320601, 320602, 320611, 320621, 320623, 320681, 320682, 320683,
			320684, 320700, 320701, 320703, 320704, 320705, 320706, 320721,
			320722, 320723, 320724, 320800, 320801, 320802, 320811, 320821,
			320826, 320829, 320830, 320831, 320882, 320900, 320901, 320902,
			320921, 320922, 320923, 320924, 320925, 320928, 320981, 320982,
			321000, 321001, 321002, 321011, 321023, 321027, 321081, 321084,
			321088, 321100, 321101, 321102, 321111, 321121, 321181, 321182,
			321183, 321200, 321201, 321202, 321203, 321281, 321282, 321283,
			321284, 321300, 321301, 321302, 321321, 321322, 321323, 321324,
			330000, 330100, 330101, 330102, 330103, 330104, 330105, 330106,
			330108, 330122, 330127, 330181, 330182, 330183, 330184, 330185,
			330200, 330201, 330203, 330204, 330205, 330206, 330211, 330225,
			330226, 330227, 330281, 330282, 330283, 330300, 330301, 330302,
			330303, 330304, 330322, 330324, 330326, 330327, 330328, 330329,
			330381, 330382, 330400, 330401, 330402, 330411, 330421, 330424,
			330481, 330482, 330483, 330500, 330501, 330521, 330522, 330523,
			330600, 330601, 330602, 330621, 330624, 330681, 330682, 330683,
			330700, 330701, 330702, 330721, 330723, 330726, 330727, 330781,
			330782, 330783, 330784, 330800, 330801, 330802, 330821, 330822,
			330824, 330825, 330881, 330900, 330901, 330902, 330903, 330921,
			330922, 331000, 331001, 331002, 331003, 331004, 331021, 331022,
			331023, 331024, 331081, 331082, 332500, 332501, 332502, 332522,
			332523, 332525, 332526, 332527, 332528, 332529, 340000, 340100,
			340101, 340102, 340103, 340104, 340111, 340121, 340122, 340123,
			340200, 340201, 340202, 340203, 340204, 340207, 340221, 340222,
			340223, 340300, 340301, 340302, 340303, 340304, 340311, 340321,
			340322, 340323, 340400, 340401, 340402, 340403, 340404, 340405,
			340406, 340421, 340500, 340501, 340502, 340503, 340504, 340505,
			340521, 340600, 340601, 340602, 340603, 340604, 340621, 340700,
			340701, 340702, 340703, 340711, 340721, 340800, 340801, 340802,
			340803, 340811, 340822, 340823, 340824, 340825, 340826, 340827,
			340828, 340881, 341000, 341001, 341002, 341003, 341004, 341021,
			341022, 341023, 341024, 341100, 341101, 341102, 341103, 341122,
			341124, 341125, 341126, 341181, 341182, 341200, 341201, 341202,
			341203, 341204, 341221, 341222, 341223, 341224, 341225, 341226,
			341227, 341281, 341282, 341300, 341301, 341302, 341321, 341322,
			341323, 341324, 342400, 342401, 342422, 342423, 342425, 342426,
			342427, 342500, 342501, 342502, 342522, 342523, 342529, 342530,
			342531, 342600, 342601, 342622, 342623, 342625, 342626, 342900,
			342901, 342921, 342922, 342923, 350000, 350100, 350101, 350102,
			350103, 350104, 350105, 350111, 350121, 350122, 350123, 350124,
			350125, 350128, 350181, 350182, 350200, 350201, 350202, 350203,
			350204, 350205, 350206, 350211, 350212, 350300, 350301, 350302,
			350303, 350321, 350322, 350400, 350401, 350402, 350403, 350421,
			350423, 350424, 350425, 350426, 350427, 350428, 350429, 350430,
			350481, 350500, 350501, 350502, 350503, 350504, 350521, 350524,
			350525, 350526, 350527, 350581, 350582, 350583, 350600, 350601,
			350602, 350603, 350622, 350623, 350624, 350625, 350626, 350627,
			350628, 350629, 350681, 350700, 350701, 350702, 350721, 350722,
			350723, 350724, 350725, 350781, 350782, 350783, 350784, 350800,
			350801, 350802, 350821, 350822, 350823, 350824, 350825, 350881,
			352200, 352201, 352202, 352203, 352225, 352227, 352228, 352229,
			352230, 352231, 360000, 360100, 360101, 360102, 360103, 360104,
			360105, 360111, 360121, 360122, 360123, 360124, 360200, 360201,
			360202, 360203, 360222, 360281, 360300, 360301, 360302, 360313,
			360321, 360322, 360323, 360400, 360401, 360402, 360403, 360421,
			360423, 360424, 360425, 360426, 360427, 360428, 360429, 360430,
			360481, 360500, 360501, 360502, 360521, 360600, 360601, 360602,
			360622, 360681, 360700, 360701, 360702, 360721, 360722, 360723,
			360724, 360725, 360726, 360727, 360728, 360729, 360730, 360731,
			360732, 360733, 360734, 360735, 360781, 360782, 362200, 362201,
			362202, 362203, 362204, 362226, 362227, 362228, 362229, 362232,
			362233, 362300, 362301, 362302, 362321, 362322, 362323, 362324,
			362325, 362326, 362329, 362330, 362331, 362334, 362400, 362401,
			362402, 362421, 362422, 362423, 362424, 362425, 362426, 362427,
			362428, 362429, 362430, 362432, 362500, 362502, 362522, 362523,
			362524, 362525, 362526, 362527, 362528, 362529, 362531, 362532,
			370000, 370100, 370101, 370102, 370103, 370104, 370105, 370112,
			370123, 370124, 370125, 370126, 370181, 370200, 370201, 370202,
			370203, 370205, 370211, 370212, 370213, 370214, 370281, 370282,
			370283, 370284, 370285, 370300, 370301, 370302, 370303, 370304,
			370305, 370306, 370321, 370322, 370323, 370400, 370401, 370402,
			370403, 370404, 370405, 370406, 370481, 370500, 370501, 370502,
			370503, 370521, 370522, 370523, 370600, 370601, 370602, 370611,
			370612, 370613, 370634, 370681, 370682, 370683, 370684, 370685,
			370686, 370687, 370700, 370701, 370702, 370703, 370704, 370705,
			370724, 370725, 370781, 370782, 370783, 370784, 370785, 370786,
			370800, 370801, 370802, 370811, 370826, 370827, 370828, 370829,
			370830, 370831, 370832, 370881, 370882, 370883, 370900, 370901,
			370902, 370911, 370921, 370923, 370982, 370983, 371000, 371001,
			371002, 371081, 371082, 371083, 371100, 371101, 371102, 371121,
			371122, 371200, 371201, 371202, 371203, 371300, 371301, 371302,
			371311, 371312, 371321, 371322, 371323, 371324, 371325, 371326,
			371327, 371328, 371329, 371400, 371401, 371402, 371421, 371422,
			371423, 371424, 371425, 371426, 371427, 371428, 371481, 371482,
			371500, 371501, 371502, 371521, 371522, 371523, 371524, 371525,
			371526, 371581, 372300, 372301, 372321, 372323, 372324, 372325,
			372328, 372330, 372900, 372901, 372922, 372923, 372924, 372925,
			372926, 372928, 372929, 372930, 410000, 410100, 410101, 410102,
			410103, 410104, 410105, 410106, 410108, 410122, 410181, 410182,
			410183, 410184, 410185, 410200, 410201, 410202, 410203, 410204,
			410205, 410211, 410221, 410222, 410223, 410224, 410225, 410300,
			410301, 410302, 410303, 410304, 410305, 410306, 410311, 410322,
			410323, 410324, 410325, 410326, 410327, 410328, 410329, 410381,
			410400, 410401, 410402, 410403, 410404, 410411, 410421, 410422,
			410423, 410425, 410481, 410482, 410500, 410501, 410502, 410503,
			410504, 410511, 410522, 410523, 410526, 410527, 410581, 410600,
			410601, 410602, 410603, 410611, 410621, 410622, 410700, 410701,
			410702, 410703, 410704, 410711, 410721, 410724, 410725, 410726,
			410727, 410728, 410781, 410782, 410800, 410801, 410802, 410803,
			410804, 410811, 410821, 410822, 410823, 410825, 410881, 410882,
			410883, 410900, 410901, 410902, 410922, 410923, 410926, 410927,
			410928, 411000, 411001, 411002, 411023, 411024, 411025, 411081,
			411082, 411100, 411101, 411102, 411121, 411122, 411123, 411200,
			411201, 411202, 411221, 411222, 411224, 411281, 411282, 411300,
			411301, 411302, 411303, 411321, 411322, 411323, 411324, 411325,
			411326, 411327, 411328, 411329, 411330, 411381, 411400, 411401,
			411402, 411403, 411421, 411422, 411423, 411424, 411425, 411426,
			411481, 411500, 411501, 411502, 411503, 411521, 411522, 411523,
			411524, 411525, 411526, 411527, 411528, 412700, 412701, 412702,
			412721, 412722, 412723, 412724, 412725, 412726, 412727, 412728,
			412800, 412801, 412821, 412822, 412823, 412824, 412825, 412826,
			412827, 412828, 412829, 420000, 420100, 420101, 420102, 420103,
			420104, 420105, 420106, 420107, 420111, 420112, 420113, 420114,
			420115, 420116, 420117, 420200, 420201, 420202, 420203, 420204,
			420205, 420222, 420281, 420300, 420301, 420302, 420303, 420321,
			420322, 420323, 420324, 420325, 420381, 420500, 420501, 420502,
			420503, 420504, 420505, 420521, 420525, 420526, 420527, 420528,
			420529, 420581, 420582, 420583, 420600, 420601, 420602, 420606,
			420621, 420624, 420625, 420626, 420682, 420683, 420684, 420700,
			420701, 420702, 420703, 420704, 420800, 420801, 420802, 420821,
			420822, 420881, 420900, 420901, 420902, 420921, 420922, 420923,
			420981, 420982, 420983, 420984, 421000, 421001, 421002, 421003,
			421022, 421023, 421024, 421081, 421083, 421087, 421100, 421101,
			421102, 421121, 421122, 421123, 421124, 421125, 421126, 421127,
			421181, 421182, 421200, 421201, 421202, 421221, 421222, 421223,
			421224, 422800, 422801, 422802, 422822, 422823, 422825, 422826,
			422827, 422828, 429000, 429001, 429004, 429005, 429006, 429021,
			430000, 430100, 430101, 430102, 430103, 430104, 430105, 430111,
			430121, 430122, 430124, 430181, 430200, 430201, 430202, 430203,
			430204, 430211, 430221, 430223, 430224, 430225, 430281, 430300,
			430301, 430302, 430304, 430321, 430381, 430382, 430400, 430401,
			430402, 430403, 430404, 430411, 430412, 430421, 430422, 430423,
			430424, 430426, 430481, 430482, 430500, 430501, 430502, 430503,
			430511, 430521, 430522, 430523, 430524, 430525, 430527, 430528,
			430529, 430581, 430600, 430601, 430602, 430603, 430611, 430621,
			430623, 430624, 430626, 430681, 430682, 430700, 430701, 430702,
			430703, 430721, 430722, 430723, 430724, 430725, 430726, 430781,
			430800, 430801, 430802, 430811, 430821, 430822, 430900, 430901,
			430902, 430903, 430921, 430922, 430923, 430981, 431000, 431001,
			431002, 431003, 431021, 431022, 431023, 431024, 431025, 431026,
			431027, 431028, 431081, 431100, 431101, 431102, 431103, 431121,
			431122, 431123, 431124, 431125, 431126, 431127, 431128, 431129,
			431200, 431201, 431202, 431221, 431222, 431223, 431224, 431225,
			431226, 431227, 431228, 431229, 431230, 431281, 432500, 432501,
			432502, 432503, 432522, 432524, 433000, 433001, 433100, 433101,
			433122, 433123, 433124, 433125, 433126, 433127, 433130, 440000,
			440100, 440101, 440102, 440103, 440104, 440105, 440106, 440107,
			440111, 440112, 440181, 440182, 440183, 440184, 440200, 440201,
			440202, 440203, 440204, 440221, 440222, 440224, 440229, 440232,
			440233, 440281, 440282, 440300, 440301, 440303, 440304, 440305,
			440306, 440307, 440308, 440400, 440401, 440402, 440421, 440500,
			440501, 440506, 440507, 440508, 440509, 440510, 440523, 440582,
			440583, 440600, 440601, 440602, 440603, 440681, 440682, 440683,
			440684, 440700, 440701, 440703, 440704, 440781, 440782, 440783,
			440784, 440785, 440800, 440801, 440802, 440803, 440804, 440811,
			440823, 440825, 440881, 440882, 440883, 440900, 440901, 440902,
			440923, 440981, 440982, 440983, 441200, 441201, 441202, 441203,
			441223, 441224, 441225, 441226, 441283, 441284, 441300, 441301,
			441302, 441322, 441323, 441324, 441381, 441400, 441401, 441402,
			441421, 441422, 441423, 441424, 441426, 441427, 441481, 441500,
			441501, 441502, 441521, 441523, 441581, 441600, 441601, 441602,
			441621, 441622, 441623, 441624, 441625, 441700, 441701, 441702,
			441721, 441723, 441781, 441800, 441801, 441802, 441821, 441823,
			441825, 441826, 441827, 441881, 441882, 441900, 441901, 442000,
			442001, 445100, 445101, 445102, 445121, 445122, 445200, 445201,
			445202, 445221, 445222, 445224, 445281, 445300, 445301, 445302,
			445321, 445322, 445323, 445381, 450000, 450100, 450101, 450102,
			450103, 450104, 450105, 450106, 450111, 450121, 450122, 450200,
			450201, 450202, 450203, 450204, 450205, 450211, 450221, 450222,
			450300, 450301, 450302, 450303, 450304, 450305, 450311, 450321,
			450322, 450323, 450324, 450325, 450326, 450327, 450328, 450329,
			450330, 450331, 450332, 450400, 450401, 450403, 450404, 450411,
			450421, 450422, 450423, 450481, 450500, 450501, 450502, 450503,
			450512, 450521, 450600, 450601, 450602, 450603, 450621, 450681,
			450700, 450701, 450702, 450703, 450721, 450722, 450800, 450801,
			450802, 450803, 450821, 450881, 450900, 450901, 450902, 450921,
			450922, 450923, 450924, 450981, 452100, 452101, 452122, 452123,
			452124, 452126, 452127, 452128, 452129, 452130, 452131, 452132,
			452133, 452200, 452201, 452223, 452224, 452225, 452226, 452227,
			452228, 452229, 452230, 452231, 452400, 452402, 452424, 452427,
			452428, 452600, 452601, 452622, 452623, 452624, 452625, 452626,
			452627, 452628, 452629, 452630, 452631, 452632, 452700, 452701,
			452702, 452723, 452724, 452725, 452726, 452727, 452728, 452729,
			452730, 452731, 460000, 460001, 460002, 460003, 460004, 460005,
			460006, 460007, 460025, 460026, 460027, 460028, 460030, 460031,
			460033, 460034, 460035, 460036, 460037, 460038, 460039, 460100,
			460101, 460102, 460103, 460104, 460200, 460201, 500000, 500100,
			500101, 500102, 500103, 500104, 500105, 500106, 500107, 500108,
			500109, 500110, 500111, 500112, 500113, 500200, 500221, 500222,
			500223, 500224, 500225, 500226, 500227, 500228, 500229, 500230,
			500231, 500232, 500233, 500234, 500235, 500236, 500237, 500238,
			500239, 500240, 500241, 500242, 500243, 500300, 500381, 500382,
			500383, 500384, 510000, 510100, 510101, 510104, 510105, 510106,
			510107, 510108, 510112, 510113, 510121, 510122, 510123, 510124,
			510125, 510129, 510131, 510132, 510181, 510182, 510183, 510184,
			510300, 510301, 510302, 510303, 510304, 510311, 510321, 510322,
			510400, 510401, 510402, 510403, 510411, 510421, 510422, 510500,
			510501, 510502, 510503, 510504, 510521, 510522, 510524, 510525,
			510600, 510601, 510603, 510623, 510626, 510681, 510682, 510683,
			510700, 510701, 510703, 510704, 510722, 510723, 510724, 510725,
			510726, 510727, 510781, 510800, 510801, 510802, 510811, 510812,
			510821, 510822, 510823, 510824, 510900, 510901, 510902, 510921,
			510922, 510923, 511000, 511001, 511002, 511011, 511024, 511025,
			511028, 511100, 511101, 511102, 511111, 511112, 511113, 511123,
			511124, 511126, 511129, 511132, 511133, 511181, 511300, 511301,
			511302, 511303, 511304, 511321, 511322, 511323, 511324, 511325,
			511381, 511500, 511501, 511502, 511521, 511522, 511523, 511524,
			511525, 511526, 511527, 511528, 511529, 511600, 511601, 511602,
			511621, 511622, 511623, 511681, 513000, 513001, 513002, 513021,
			513022, 513023, 513029, 513030, 513100, 513101, 513122, 513123,
			513124, 513125, 513126, 513127, 513128, 513200, 513221, 513222,
			513223, 513224, 513225, 513226, 513227, 513228, 513229, 513230,
			513231, 513232, 513233, 513300, 513321, 513322, 513323, 513324,
			513325, 513326, 513327, 513328, 513329, 513330, 513331, 513332,
			513333, 513334, 513335, 513336, 513337, 513338, 513400, 513401,
			513422, 513423, 513424, 513425, 513426, 513427, 513428, 513429,
			513430, 513431, 513432, 513433, 513434, 513435, 513436, 513437,
			513700, 513701, 513721, 513722, 513723, 513800, 513821, 513822,
			513823, 513824, 513825, 513826, 513900, 513901, 513902, 513921,
			513922, 520000, 520100, 520101, 520102, 520103, 520111, 520112,
			520113, 520121, 520122, 520123, 520181, 520200, 520201, 520202,
			520203, 520221, 520300, 520301, 520302, 520321, 520322, 520323,
			520324, 520325, 520326, 520327, 520328, 520329, 520330, 520381,
			520382, 522200, 522201, 522222, 522223, 522224, 522225, 522226,
			522227, 522228, 522229, 522230, 522300, 522301, 522322, 522323,
			522324, 522325, 522326, 522327, 522328, 522400, 522401, 522422,
			522423, 522424, 522425, 522426, 522427, 522428, 522500, 522501,
			522526, 522527, 522528, 522529, 522530, 522600, 522601, 522622,
			522623, 522624, 522625, 522626, 522627, 522628, 522629, 522630,
			522631, 522632, 522633, 522634, 522635, 522636, 522700, 522701,
			522702, 522722, 522723, 522725, 522726, 522727, 522728, 522729,
			522730, 522731, 522732, 530000, 530100, 530101, 530102, 530103,
			530111, 530112, 530113, 530121, 530122, 530124, 530125, 530126,
			530127, 530128, 530129, 530181, 530300, 530301, 530302, 530321,
			530322, 530323, 530324, 530325, 530326, 530328, 530381, 530400,
			530401, 530402, 530421, 530422, 530423, 530424, 530425, 530426,
			530427, 530428, 532100, 532101, 532122, 532123, 532124, 532125,
			532126, 532127, 532128, 532129, 532130, 532131, 532300, 532301,
			532322, 532323, 532324, 532325, 532326, 532327, 532328, 532329,
			532331, 532500, 532501, 532502, 532522, 532523, 532524, 532525,
			532526, 532527, 532528, 532529, 532530, 532531, 532532, 532600,
			532621, 532622, 532623, 532624, 532625, 532626, 532627, 532628,
			532700, 532701, 532722, 532723, 532724, 532725, 532726, 532727,
			532728, 532729, 532730, 532800, 532801, 532822, 532823, 532900,
			532901, 532922, 532923, 532924, 532925, 532926, 532927, 532928,
			532929, 532930, 532931, 532932, 533000, 533001, 533022, 533023,
			533024, 533025, 533100, 533101, 533102, 533103, 533122, 533123,
			533124, 533200, 533221, 533222, 533223, 533224, 533300, 533321,
			533323, 533324, 533325, 533400, 533421, 533422, 533423, 533500,
			533521, 533522, 533523, 533524, 533525, 533526, 533527, 533528,
			540000, 540100, 540101, 540102, 540121, 540122, 540123, 540124,
			540125, 540126, 540127, 542100, 542121, 542122, 542123, 542124,
			542125, 542126, 542127, 542128, 542129, 542132, 542133, 542134,
			542135, 542136, 542137, 542200, 542221, 542222, 542223, 542224,
			542225, 542226, 542227, 542228, 542229, 542231, 542232, 542233,
			542300, 542301, 542322, 542323, 542324, 542325, 542326, 542327,
			542328, 542329, 542330, 542331, 542332, 542333, 542334, 542335,
			542336, 542337, 542338, 542400, 542421, 542422, 542423, 542424,
			542425, 542426, 542427, 542428, 542429, 542430, 542500, 542521,
			542522, 542523, 542524, 542525, 542526, 542527, 542528, 542600,
			542621, 542622, 542623, 542624, 542625, 542626, 542627, 610000,
			610100, 610101, 610102, 610103, 610104, 610111, 610112, 610113,
			610114, 610115, 610121, 610122, 610124, 610125, 610126, 610200,
			610201, 610202, 610203, 610221, 610222, 610300, 610301, 610302,
			610303, 610321, 610322, 610323, 610324, 610326, 610327, 610328,
			610329, 610330, 610331, 610400, 610401, 610402, 610403, 610404,
			610422, 610423, 610424, 610425, 610426, 610427, 610428, 610429,
			610430, 610431, 610481, 610500, 610501, 610502, 610521, 610522,
			610523, 610524, 610525, 610526, 610527, 610528, 610581, 610582,
			610600, 610601, 610602, 610621, 610622, 610623, 610624, 610625,
			610626, 610627, 610628, 610629, 610630, 610631, 610632, 610700,
			610701, 610702, 610721, 610722, 610723, 610724, 610725, 610726,
			610727, 610728, 610729, 610730, 612400, 612401, 612422, 612423,
			612424, 612425, 612426, 612427, 612428, 612429, 612430, 612500,
			612501, 612522, 612523, 612524, 612525, 612526, 612527, 612700,
			612701, 612722, 612723, 612724, 612725, 612726, 612727, 612728,
			612729, 612730, 612731, 612732, 620000, 620100, 620101, 620102,
			620103, 620104, 620105, 620111, 620121, 620122, 620123, 620200,
			620201, 620300, 620301, 620302, 620321, 620400, 620401, 620402,
			620403, 620421, 620422, 620423, 620500, 620501, 620502, 620503,
			620521, 620522, 620523, 620524, 620525, 622100, 622101, 622102,
			622103, 622123, 622124, 622125, 622126, 622200, 622201, 622222,
			622223, 622224, 622225, 622226, 622300, 622301, 622322, 622323,
			622326, 622400, 622421, 622424, 622425, 622426, 622427, 622428,
			622429, 622600, 622621, 622623, 622624, 622625, 622626, 622627,
			622628, 622629, 622630, 622700, 622701, 622722, 622723, 622724,
			622725, 622726, 622727, 622800, 622801, 622821, 622822, 622823,
			622824, 622825, 622826, 622827, 622900, 622901, 622921, 622922,
			622923, 622924, 622925, 622926, 622927, 623000, 623001, 623021,
			623022, 623023, 623024, 623025, 623026, 623027, 630000, 630100,
			630101, 630102, 630103, 630104, 630105, 630121, 632100, 632121,
			632122, 632123, 632124, 632125, 632126, 632127, 632128, 632200,
			632221, 632222, 632223, 632224, 632300, 632321, 632322, 632323,
			632324, 632500, 632521, 632522, 632523, 632524, 632525, 632600,
			632621, 632622, 632623, 632624, 632625, 632626, 632700, 632721,
			632722, 632723, 632724, 632725, 632726, 632800, 632801, 632802,
			632821, 632822, 632823, 640000, 640100, 640101, 640102, 640103,
			640111, 640121, 640122, 640200, 640201, 640202, 640203, 640204,
			640221, 640222, 640223, 640300, 640301, 640302, 640321, 640322,
			640323, 640324, 640381, 640382, 642200, 642221, 642222, 642223,
			642224, 642225, 642226, 650000, 650100, 650101, 650102, 650103,
			650104, 650105, 650106, 650107, 650108, 650121, 650200, 650201,
			650202, 650203, 650204, 650205, 652100, 652101, 652122, 652123,
			652200, 652201, 652222, 652223, 652300, 652301, 652302, 652303,
			652323, 652324, 652325, 652327, 652328, 652700, 652701, 652722,
			652723, 652800, 652801, 652822, 652823, 652824, 652825, 652826,
			652827, 652828, 652829, 652900, 652901, 652922, 652923, 652924,
			652925, 652926, 652927, 652928, 652929, 653000, 653001, 653022,
			653023, 653024, 653100, 653101, 653121, 653122, 653123, 653124,
			653125, 653126, 653127, 653128, 653129, 653130, 653131, 653200,
			653201, 653221, 653222, 653223, 653224, 653225, 653226, 653227,
			654000, 654001, 654100, 654101, 654121, 654122, 654123, 654124,
			654125, 654126, 654127, 654128, 654200, 654201, 654202, 654221,
			654223, 654224, 654225, 654226, 654300, 654301, 654321, 654322,
			654323, 654324, 654325, 654326, 659000, 659001 };
}
